package jnpf.service.impl;

import jnpf.util.UserProvider;
import jnpf.entity.*;
import jnpf.mapper.TagMapper;
import jnpf.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.model.tag.*;
import cn.hutool.core.util.ObjectUtil;
import jnpf.util.GeneraterSwapUtil;

import java.lang.reflect.Field;
import com.baomidou.mybatisplus.annotation.TableField;
import jnpf.model.QueryModel;
import java.util.stream.Collectors;
import jnpf.base.model.ColumnDataModel;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import jnpf.database.model.superQuery.SuperJsonModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jnpf.util.*;
import java.util.*;
import jnpf.base.UserInfo;
import jnpf.permission.entity.UserEntity;
/**
 *
 * tag
 * 版本： V3.5
 * 版权： 引迈信息技术有限公司（https://www.jnpfsoft.com）
 * 作者： JNPF开发平台组
 * 日期： 2025-04-12
 */
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, TagEntity> implements TagService{
    @Autowired
    private GeneraterSwapUtil generaterSwapUtil;

    @Autowired
    private UserProvider userProvider;

    @Autowired
    private TagRelationService tagRelationService;
    @Override
    public List<TagEntity> getList(TagPagination tagPagination){
        return getTypeList(tagPagination,tagPagination.getDataType());
    }
    /** 列表查询 */
    @Override
    public List<TagEntity> getTypeList(TagPagination tagPagination,String dataType){
        String userId=userProvider.get().getUserId();
        List<String> AllIdList =new ArrayList();
        List<List<String>> intersectionList =new ArrayList<>();
        boolean isPc = ServletUtil.getHeader("jnpf-origin").equals("pc");
        String columnData = !isPc ? TagConstant.getAppColumnData() : TagConstant.getColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        String ruleJson = !isPc ? JsonUtil.getObjectToString(columnDataModel.getRuleListApp()) : JsonUtil.getObjectToString(columnDataModel.getRuleList());

        int total=0;
        int tagNum =0;
        QueryWrapper<TagEntity> tagQueryWrapper=new QueryWrapper<>();
        int tagRelationNum =0;
        QueryWrapper<TagRelationEntity> tagRelationQueryWrapper=new QueryWrapper<>();
        long tagRelationcount = tagRelationService.count();
        List<String> allSuperIDlist = new ArrayList<>();
        String superOp ="";
        if (ObjectUtil.isNotEmpty(tagPagination.getSuperQueryJson())){
            List<String> allSuperList = new ArrayList<>();
            List<List<String>> intersectionSuperList  = new ArrayList<>();
            String queryJson = tagPagination.getSuperQueryJson();
            SuperJsonModel superJsonModel = JsonUtil.getJsonToBean(queryJson, SuperJsonModel.class);
            int superNum = 0;
            QueryWrapper<TagEntity> tagSuperWrapper = new QueryWrapper<>();
            tagSuperWrapper = generaterSwapUtil.getCondition(new QueryModel(tagSuperWrapper,TagEntity.class,queryJson,"0"));
            int tagNum1 = tagSuperWrapper.getExpression().getNormal().size();
            if (tagNum1>0){
                List<String> tagList =this.list(tagSuperWrapper).stream().map(TagEntity::getId).collect(Collectors.toList());
                allSuperList.addAll(tagList);
                intersectionSuperList.add(tagList);
                superNum++;
            }
            String tagRelationTable = "tag_relation";
            boolean tagRelationHasSql = queryJson.contains(tagRelationTable);
            List<String> tagRelationList = generaterSwapUtil.selectIdsByChildCondition(TagConstant.getTableList(), tagRelationTable , queryJson, null);
            if (tagRelationHasSql){
                allSuperList.addAll(tagRelationList);
                intersectionSuperList.add(tagRelationList);
                superNum++;
            }
            superOp = superNum > 0 ? superJsonModel.getMatchLogic() : "";
            //and or
            if(superOp.equalsIgnoreCase("and")){
                allSuperIDlist = generaterSwapUtil.getIntersection(intersectionSuperList);
            }else{
                allSuperIDlist = allSuperList;
            }
        }
        List<String> allRuleIDlist = new ArrayList<>();
        String ruleOp ="";
        if (ObjectUtil.isNotEmpty(ruleJson)){
            List<String> allRuleList = new ArrayList<>();
            List<List<String>> intersectionRuleList  = new ArrayList<>();
            SuperJsonModel ruleJsonModel = JsonUtil.getJsonToBean(ruleJson, SuperJsonModel.class);
            int ruleNum = 0;
            QueryWrapper<TagEntity> tagSuperWrapper = new QueryWrapper<>();
            tagSuperWrapper = generaterSwapUtil.getCondition(new QueryModel(tagSuperWrapper,TagEntity.class,ruleJson,"0"));
            int tagNum1 = tagSuperWrapper.getExpression().getNormal().size();
            if (tagNum1>0){
                List<String> tagList =this.list(tagSuperWrapper).stream().map(TagEntity::getId).collect(Collectors.toList());
                allRuleList.addAll(tagList);
                intersectionRuleList.add(tagList);
                ruleNum++;
            }
            String tagRelationTable = "tag_relation";
            boolean tagRelationHasSql = ruleJson.contains(tagRelationTable);
            List<String> tagRelationList = generaterSwapUtil.selectIdsByChildCondition(TagConstant.getTableList(), tagRelationTable , ruleJson, null);
            if (tagRelationHasSql){
                allRuleList.addAll(tagRelationList);
                intersectionRuleList.add(tagRelationList);
                ruleNum++;
            }
            ruleOp = ruleNum > 0 ? ruleJsonModel.getMatchLogic() : "";
            //and or
            if(ruleOp.equalsIgnoreCase("and")){
                allRuleIDlist = generaterSwapUtil.getIntersection(intersectionRuleList);
            }else{
                allRuleIDlist = allRuleList;
            }
        }
    boolean pcPermission = false;
    boolean appPermission = false;
    if(isPc && pcPermission){
    if (!userProvider.get().getIsAdministrator()){
        Object tagObj=generaterSwapUtil.getAuthorizeCondition(new QueryModel(tagQueryWrapper,TagEntity.class,tagPagination.getMenuId(),"0"));
        if (ObjectUtil.isEmpty(tagObj)){
        return new ArrayList<>();
        } else {
        tagQueryWrapper = (QueryWrapper<TagEntity>)tagObj;
        if( tagQueryWrapper.getExpression().getNormal().size()>0){
        tagNum++;
        }
        }
        Object tagRelationObj=generaterSwapUtil.getAuthorizeCondition(new QueryModel(tagRelationQueryWrapper,TagRelationEntity.class,tagPagination.getMenuId(),"0"));
        if (ObjectUtil.isEmpty(tagRelationObj)){
        return new ArrayList<>();
        } else {
        tagRelationQueryWrapper = (QueryWrapper<TagRelationEntity>)tagRelationObj;
        if( tagRelationQueryWrapper.getExpression().getNormal().size()>0){
        tagRelationNum++;
        }
        }
    }
    }
    if(!isPc && appPermission){
    if (!userProvider.get().getIsAdministrator()){
        Object tagObj=generaterSwapUtil.getAuthorizeCondition(new QueryModel(tagQueryWrapper,TagEntity.class,tagPagination.getMenuId(),"0"));
        if (ObjectUtil.isEmpty(tagObj)){
        return new ArrayList<>();
        } else {
        tagQueryWrapper = (QueryWrapper<TagEntity>)tagObj;
        if( tagQueryWrapper.getExpression().getNormal().size()>0){
        tagNum++;
        }
        }


        Object tagRelationObj=generaterSwapUtil.getAuthorizeCondition(new QueryModel(tagRelationQueryWrapper,TagRelationEntity.class,tagPagination.getMenuId(),"0"));
        if (ObjectUtil.isEmpty(tagRelationObj)){
        return new ArrayList<>();
        } else {
        tagRelationQueryWrapper = (QueryWrapper<TagRelationEntity>)tagRelationObj;
        if( tagRelationQueryWrapper.getExpression().getNormal().size()>0){
        tagRelationNum++;
        }
        }


    }
    }
        if(isPc){
            if(ObjectUtil.isNotEmpty(tagPagination.getTableField104_tagType())){
            tagRelationNum++;

        List<String> idList = new ArrayList<>();
        try {
        String[][] tagType = JsonUtil.getJsonToBean(tagPagination.getTableField104_tagType(),String[][].class);
        for(int i=0;i<tagType.length;i++){
        if(tagType[i].length>0){
        idList.add(JsonUtil.getObjectToString(Arrays.asList(tagType[i])));
        }
        }
        }catch (Exception e1){
        try {
        List<String> tagType = JsonUtil.getJsonToList(tagPagination.getTableField104_tagType(),String.class);
        if(tagType.size()>0){
            idList.addAll(tagType);
        }
        }catch (Exception e2){
        idList.add(String.valueOf(tagPagination.getTableField104_tagType()));
        }
        }
        tagRelationQueryWrapper.lambda().and(t->{
        idList.forEach(tt->{
        t.like(TagRelationEntity::getTagType, tt).or();
        });
        });

            }

            if(ObjectUtil.isNotEmpty(tagPagination.getName())){
            tagNum++;

                String value = tagPagination.getName() instanceof List ?
                    JsonUtil.getObjectToString(tagPagination.getName()) :
                    String.valueOf(tagPagination.getName());
                tagQueryWrapper.lambda().like(TagEntity::getName,value);

            }

            if(ObjectUtil.isNotEmpty(tagPagination.getTagType())){
            tagNum++;

        List<String> idList = new ArrayList<>();
        try {
        String[][] tagType = JsonUtil.getJsonToBean(tagPagination.getTagType(),String[][].class);
        for(int i=0;i<tagType.length;i++){
        if(tagType[i].length>0){
        idList.add(JsonUtil.getObjectToString(Arrays.asList(tagType[i])));
        }
        }
        }catch (Exception e1){
        try {
        List<String> tagType = JsonUtil.getJsonToList(tagPagination.getTagType(),String.class);
        if(tagType.size()>0){
            idList.addAll(tagType);
        }
        }catch (Exception e2){
        idList.add(String.valueOf(tagPagination.getTagType()));
        }
        }
        tagQueryWrapper.lambda().and(t->{
        idList.forEach(tt->{
        t.like(TagEntity::getTagType, tt).or();
        });
        });

            }

            if(ObjectUtil.isNotEmpty(tagPagination.getIsPre())){
            tagNum++;

        List<String> idList = new ArrayList<>();
        try {
        String[][] isPre = JsonUtil.getJsonToBean(tagPagination.getIsPre(),String[][].class);
        for(int i=0;i<isPre.length;i++){
        if(isPre[i].length>0){
        idList.add(JsonUtil.getObjectToString(Arrays.asList(isPre[i])));
        }
        }
        }catch (Exception e1){
        try {
        List<String> isPre = JsonUtil.getJsonToList(tagPagination.getIsPre(),String.class);
        if(isPre.size()>0){
            idList.addAll(isPre);
        }
        }catch (Exception e2){
        idList.add(String.valueOf(tagPagination.getIsPre()));
        }
        }
        tagQueryWrapper.lambda().and(t->{
        idList.forEach(tt->{
        t.like(TagEntity::getIsPre, tt).or();
        });
        });

            }

            if(ObjectUtil.isNotEmpty(tagPagination.getCreateUserId())){
            tagNum++;

                List CreateUserIdList =  JsonUtil.getJsonToList(tagPagination.getCreateUserId(),String.class);
                    Long fir = Long.valueOf(String.valueOf(CreateUserIdList.get(0)));
                    Long sec = Long.valueOf(String.valueOf(CreateUserIdList.get(1)));

                    tagQueryWrapper.lambda().ge(TagEntity::getCreateUserId, new Date(fir))
                    .le(TagEntity::getCreateUserId, DateUtil.stringToDate(DateUtil.daFormatYmd(sec) + " 23:59:59"));


            }

            if(ObjectUtil.isNotEmpty(tagPagination.getCreateTime())){
            tagNum++;

        tagQueryWrapper.lambda().eq(TagEntity::getCreateTime,tagPagination.getCreateTime());

            }

        }
            if(tagRelationNum>0){
            List<String> tagRelationIdList = tagRelationService.list(tagRelationQueryWrapper).stream().filter(t->StringUtil.isNotEmpty(t.getTagId())).map(t->t.getTagId()).collect(Collectors.toList());
            long count = tagRelationService.count();
            if (count>0){
            intersectionList.add(tagRelationIdList);
            }
            AllIdList.addAll(tagRelationIdList);
            }
            total+=tagRelationNum;
        List<String> intersection = generaterSwapUtil.getIntersection(intersectionList);
        if (total>0){
            if (intersection.size()==0){
                intersection.add("jnpfNullList");
            }
            tagQueryWrapper.lambda().in(TagEntity::getId, intersection);
        }
    //是否有高级查询
        if (StringUtil.isNotEmpty(superOp)){
            if (allSuperIDlist.size()==0){
                allSuperIDlist.add("jnpfNullList");
            }
            List<String> finalAllSuperIDlist = allSuperIDlist;
            tagQueryWrapper.lambda().and(t->t.in(TagEntity::getId, finalAllSuperIDlist));
        }
    //是否有数据过滤查询
        if (StringUtil.isNotEmpty(ruleOp)){
            if (allRuleIDlist.size()==0){
                allRuleIDlist.add("jnpfNullList");
            }
            List<String> finalAllRuleIDlist = allRuleIDlist;
            tagQueryWrapper.lambda().and(t->t.in(TagEntity::getId, finalAllRuleIDlist));
        }

        //排序
        if(StringUtil.isEmpty(tagPagination.getSidx())){
            tagQueryWrapper.lambda().orderByDesc(TagEntity::getId);
        }else{
            try {
                String sidx = tagPagination.getSidx();
                String[] strs= sidx.split("_name");
                TagEntity tagEntity = new TagEntity();
                Field declaredField = tagEntity.getClass().getDeclaredField(strs[0]);
                declaredField.setAccessible(true);
                String value = declaredField.getAnnotation(TableField.class).value();
                tagQueryWrapper="asc".equals(tagPagination.getSort().toLowerCase())?tagQueryWrapper.orderByAsc(value):tagQueryWrapper.orderByDesc(value);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }

        if("0".equals(dataType)){
            if((total>0 && AllIdList.size()>0) || total==0){
                Page<TagEntity> page=new Page<>(tagPagination.getCurrentPage(), tagPagination.getPageSize());
                IPage<TagEntity> userIPage=this.page(page, tagQueryWrapper);
                return tagPagination.setData(userIPage.getRecords(),userIPage.getTotal());
            }else{
                List<TagEntity> list = new ArrayList();
                return tagPagination.setData(list, list.size());
            }
        }else{
            return this.list(tagQueryWrapper);
        }
    }
    @Override
    public TagEntity getInfo(String id){
        QueryWrapper<TagEntity> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().eq(TagEntity::getId,id);
        return this.getOne(queryWrapper);
    }
    @Override
    public void create(TagEntity entity){
        this.save(entity);
    }
    @Override
    public boolean update(String id, TagEntity entity){
        return this.updateById(entity);
    }
    @Override
    public void delete(TagEntity entity){
        if(entity!=null){
            this.removeById(entity.getId());
        }
    }
    /** TagRelation子表方法 */
    @Override
    public List<TagRelationEntity> getTagRelationList(String id,TagPagination tagPagination){
        Map<String, Object> newtabMap=TagConstant.TABLEFIELDKEY.entrySet()
        .stream().collect( Collectors.toMap(e->e.getValue(),e->e.getKey()));
        String tableName="tagRelation";
        tableName=newtabMap.get(tableName)==null?tableName:newtabMap.get(tableName).toString();
        QueryWrapper<TagRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper = tagRelationService.getChild(tagPagination,queryWrapper);
        queryWrapper.lambda().eq(TagRelationEntity::getTagId, id);
        generaterSwapUtil.wrapperHandle(TagConstant.getColumnData(), TagConstant.getAppColumnData(), queryWrapper,TagRelationEntity.class,"sub",tableName);
        return tagRelationService.list(queryWrapper);
    }

    /** TagRelation子表方法 */
    @Override
    public List<TagRelationEntity> getTagRelationList(String id){
        QueryWrapper<TagRelationEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TagRelationEntity::getTagId, id);
        return tagRelationService.list(queryWrapper);
    }
    /** 验证表单唯一字段，正则，非空 i-0新增-1修改*/
    @Override
    public String checkForm(TagForm form,int i) {
        boolean isUp =StringUtil.isNotEmpty(form.getId()) && !form.getId().equals("0");
        String id="";
        String countRecover = "";
        if (isUp){
            id = form.getId();
        }
        //主表字段验证
                if(StringUtil.isEmpty(form.getName())){
                    return "标签名称不能为空";
                }
                if(StringUtil.isNotEmpty(form.getName())){
                    form.setName(form.getName().trim());
                    QueryWrapper<TagEntity> nameWrapper=new QueryWrapper<>();
                    nameWrapper.lambda().eq(TagEntity::getName,form.getName());
                    if (isUp){
                        nameWrapper.lambda().ne(TagEntity::getId, id);
                    }
                    if((int) this.count(nameWrapper)>0){
                        countRecover = "标签名称不能重复";
                    }
                }
        //子表字段验证
            if (form.getTagRelationList()!=null){
            }
        return countRecover;
    }
    /**
    * 新增修改数据(事务回滚)
    * @param id
    * @param tagForm
    * @return
    */
    @Override
    @Transactional
    public void saveOrUpdate(TagForm tagForm,String id, boolean isSave) throws Exception{
        UserInfo userInfo=userProvider.get();
        UserEntity userEntity = generaterSwapUtil.getUser(userInfo.getUserId());
        tagForm = JsonUtil.getJsonToBean(
        generaterSwapUtil.swapDatetime(TagConstant.getFormData(),tagForm),TagForm.class);
        TagEntity entity = JsonUtil.getJsonToBean(tagForm, TagEntity.class);

        if(isSave){
            String mainId =  RandomUtil.uuId() ;
            entity.setCreateUserId(userInfo.getUserId());
            entity.setCreateTime(DateUtil.getNowDate());
            entity.setId(mainId);
        }else{
            entity.setCreateUserId(userInfo.getUserId());
            entity.setCreateTime(DateUtil.getNowDate());
        }
        this.saveOrUpdate(entity);

        //TagRelation子表数据新增修改
        if(!isSave){
            QueryWrapper<TagRelationEntity> TagRelationqueryWrapper = new QueryWrapper<>();
            TagRelationqueryWrapper.lambda().eq(TagRelationEntity::getTagId, entity.getId());
            tagRelationService.remove(TagRelationqueryWrapper);
        }
        if (tagForm.getTagRelationList()!=null){
            List<TagRelationEntity> tableField104 = JsonUtil.getJsonToList(tagForm.getTagRelationList(),TagRelationEntity.class);
            for(TagRelationEntity entitys : tableField104){
                entitys.setId(RandomUtil.uuId());
                entitys.setTagId(entity.getId());
                if(isSave){
                }else{
                }
                tagRelationService.saveOrUpdate(entitys);
            }
        }
    }

    @Override
    public int getTagSonSize(String treeActiveId) {
        List<TagRelationEntity> list = tagRelationService.lambdaQuery().eq(TagRelationEntity::getTagId, treeActiveId).list();
        return list.size();
    }
}
